#pragma once 

#include<iostream>
#include<pthread.h>
#include<vector>
#include<semaphore.h>

//using namespace std;


const static int defaultcap = 6;

template<class T>
class Ringqueue
{
private:
std::vector<T> _ringqueue;
int _cap;
int _c_step;
int _p_step;
//信号量
sem_t _cdata_sem;//消费者信号量
sem_t _pspace_sem;//生产者信号量
//互斥锁
pthread_mutex_t _mutex_c;
pthread_mutex_t _mutex_p;
 
public:
    Ringqueue(int cap = defaultcap)
    :_ringqueue(cap),_cap(cap),_c_step(0),_p_step(0)
    {
        sem_init(&_cdata_sem,0,0);
        sem_init(&_pspace_sem,0,cap);

        pthread_mutex_init(&_mutex_c,nullptr);
        pthread_mutex_init(&_mutex_p,nullptr);
    }
    ~Ringqueue()
    {
        sem_destroy(&_cdata_sem);
        sem_destroy(&_pspace_sem);

        pthread_mutex_destroy(&_mutex_c);
        pthread_mutex_destroy(&_mutex_p);
    }

    void push(const T& in)
    {
        //P空间，减少空间
        sem_wait(&_pspace_sem);

        pthread_mutex_lock(&_mutex_p);
        _ringqueue[_p_step++] = in;

        _p_step %= _cap;//保持环形

        pthread_mutex_unlock(&_mutex_p);

        //V数据，增加数据空间
        sem_post(&_cdata_sem);

    }

    T pop()
    {
        //减少数据
        sem_wait(&_cdata_sem);
        pthread_mutex_lock(&_mutex_c);

        T data = _ringqueue[_c_step++];

        _c_step %= _cap;

        pthread_mutex_unlock(&_mutex_c);

        //增加储存空间
        sem_post(&_pspace_sem);


        return data;
        
    }
    

};